// ignore_for_file: library_private_types_in_public_api, constant_identifier_names

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:kmxy_base/util/time_util.dart';
import 'package:kmxy_base/widget/divider_kmxy.dart';


typedef DatetimeSelectFun = Function(String time);

enum DatetimeMode { yyyy, MM, dd, HH, mm, ss }

class DatetimeSelectView extends StatefulWidget {
  final List<DatetimeMode> datetimeModeList;
  final String? title;
  final DateTime? maxTime;
  final DateTime? minTime;
  final DateTime? currentTime;
  final DatetimeSelectFun onTime;

  const DatetimeSelectView({
    required this.datetimeModeList,
    this.title,
    this.maxTime,
    this.minTime,
    this.currentTime,
    required this.onTime,
    Key? key,
  }) : super(key: key);

  @override
  _DatetimeSelectViewState createState() => _DatetimeSelectViewState();
}

class _DatetimeSelectViewState extends State<DatetimeSelectView> {
  TextEditingController controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
      constraints: BoxConstraints(maxHeight: 280.w),
      child: Column(
        children: [
          Row(
            children: [
              InkWell(
                  onTap: cancel,
                  child: Container(
                      padding: EdgeInsets.all(10.w), child: const Text('取消'))),
              Expanded(
                  child: Container(
                      padding: EdgeInsets.all(10.w),
                      child: Text(widget.title ?? '',
                          textAlign: TextAlign.center))),
              InkWell(
                  onTap: commit,
                  child: Container(
                      padding: EdgeInsets.all(10.w), child: const Text('确定'))),
            ],
          ),
          const DividerKmxy(height: 0),
          Expanded(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(
                widget.datetimeModeList.length,
                (index) => itemView(widget.datetimeModeList[index]),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget itemView(DatetimeMode mode) {
    Map data = dataMake(mode);
    if (data.isEmpty) {
      return Container();
    }
    if (widget.datetimeModeList.length == 6 && mode == DatetimeMode.yyyy) {
      return SizedBox(
        width: 80.w,
        child: CupertinoPicker.builder(
          scrollController: data['controller'],
          itemExtent: 30.w,
          onSelectedItemChanged: (int selectIndex) => onSelectedItemChanged(
              data['list'][selectIndex], selectIndex, mode),
          childCount: data['list'].length,
          itemBuilder: (BuildContext context, index) {
            return Align(
                alignment: Alignment.center,
                child: Text(
                  '${data['list'][index]}${data['unit']}',
                  style: TextStyle(fontSize: 16.w),
                ));
          },
        ),
      );
    }

    return Expanded(
      child: CupertinoPicker.builder(
        scrollController: data['controller'],
        itemExtent: 30.w,
        onSelectedItemChanged: (int selectIndex) =>
            onSelectedItemChanged(data['list'][selectIndex], selectIndex, mode),
        childCount: data['list'].length,
        itemBuilder: (BuildContext context, index) {
          return Align(
              alignment: Alignment.center,
              child: Text(
                '${data['list'][index]}${data['unit']}',
                style: TextStyle(fontSize: 16.w),
              ));
        },
      ),
    );
  }

  Map dataMake(DatetimeMode mode) {
    if (mode == DatetimeMode.yyyy) {
      return {
        'unit': '年',
        'list': yearList,
        'controller': yearFixedExtentScrollController
      };
    }
    if (mode == DatetimeMode.MM) {
      return {
        'unit': '月',
        'list': monthList,
        'controller': monthFixedExtentScrollController
      };
    }
    if (mode == DatetimeMode.dd) {
      return {
        'unit': '日',
        'list': dayList,
        'controller': dayFixedExtentScrollController
      };
    }
    if (mode == DatetimeMode.HH) {
      return {
        'unit': '时',
        'list': hourList,
        'controller': hourFixedExtentScrollController
      };
    }
    if (mode == DatetimeMode.mm) {
      return {
        'unit': '分',
        'list': minuteList,
        'controller': minuteFixedExtentScrollController
      };
    }
    if (mode == DatetimeMode.ss) {
      return {
        'unit': '秒',
        'list': secondList,
        'controller': secondFixedExtentScrollController
      };
    }
    return {};
  }

  FixedExtentScrollController? yearFixedExtentScrollController;
  FixedExtentScrollController? monthFixedExtentScrollController;
  FixedExtentScrollController? dayFixedExtentScrollController;
  FixedExtentScrollController? hourFixedExtentScrollController;
  FixedExtentScrollController? minuteFixedExtentScrollController;
  FixedExtentScrollController? secondFixedExtentScrollController;

  List<int> yearList = [];
  List<int> monthList = [];
  List<int> dayList = [];
  List<int> hourList = [];
  List<int> minuteList = [];
  List<int> secondList = [];

  int yearIndex = 0;
  int monthIndex = 0;
  int dayIndex = 0;
  int hourIndex = 0;
  int minuteIndex = 0;
  int secondIndex = 0;

  late DateTime minTime;
  late DateTime maxTime;
  late DateTime currentTime;

  @override
  void initState() {
    super.initState();
    minTime = widget.minTime ?? DateTime(1900, 1, 1, 0, 0, 0);
    maxTime = widget.maxTime ?? DateTime(2100, 12, 31, 23, 59, 59);
    currentTime = widget.currentTime ?? DateTime.now();
    if (currentTime.millisecondsSinceEpoch < minTime.millisecondsSinceEpoch) {
      currentTime = minTime;
    }

    if (currentTime.millisecondsSinceEpoch > maxTime.millisecondsSinceEpoch) {
      currentTime = maxTime;
    }

    yearList.addAll(TimeUtil.calcYear(begin: minTime.year, end: maxTime.year));

    monthList
        .addAll(TimeUtil.calcMonth(begin: monthMinMake(), end: monthMaxMake()));

    dayList.addAll(TimeUtil.calcDay(yearList[yearIndex], monthList[monthIndex],
        begin: dayMinMake(), end: dayMaxMake()));

    hourList
        .addAll(TimeUtil.calcHour(begin: hourMinMake(), end: hourMaxMake()));
    minuteList.addAll(TimeUtil.calcMinAndSecond(
        begin: minuteMinMake(), end: minuteMaxMake()));
    secondList.addAll(TimeUtil.calcMinAndSecond(
        begin: secondMinMake(), end: secondMaxMake()));

    yearIndex = yearList.indexOf(currentTime.year);
    monthIndex = monthList.indexOf(currentTime.month);
    dayIndex = dayList.indexOf(currentTime.day);
    hourIndex = hourList.indexOf(currentTime.hour);
    minuteIndex = minuteList.indexOf(currentTime.minute);
    secondIndex = secondList.indexOf(currentTime.second);

    yearFixedExtentScrollController =
        FixedExtentScrollController(initialItem: yearIndex);
    monthFixedExtentScrollController =
        FixedExtentScrollController(initialItem: monthIndex);
    dayFixedExtentScrollController =
        FixedExtentScrollController(initialItem: dayIndex);
    hourFixedExtentScrollController =
        FixedExtentScrollController(initialItem: hourIndex);
    minuteFixedExtentScrollController =
        FixedExtentScrollController(initialItem: minuteIndex);
    secondFixedExtentScrollController =
        FixedExtentScrollController(initialItem: secondIndex);
    setState(() {});
  }

  int monthMinMake() {
    if (currentTime.year == minTime.year) {
      return minTime.month;
    }
    return 1;
  }

  int monthMaxMake() {
    if (currentTime.year == maxTime.year) {
      return maxTime.month;
    }
    return 12;
  }

  int dayMinMake() {
    if (currentTime.year == minTime.year &&
        currentTime.month == minTime.month) {
      return minTime.day;
    }
    return 1;
  }

  int dayMaxMake() {
    if (currentTime.year == maxTime.year &&
        currentTime.month == maxTime.month) {
      return maxTime.day;
    }
    return TimeUtil.calcDateCount(currentTime.year, currentTime.month);
  }

  int hourMinMake() {
    if (currentTime.year == minTime.year &&
        currentTime.month == minTime.month &&
        currentTime.day == minTime.day) {
      return minTime.hour;
    }
    return 0;
  }

  int hourMaxMake() {
    if (currentTime.year == maxTime.year &&
        currentTime.month == maxTime.month &&
        currentTime.day == maxTime.day) {
      return maxTime.hour;
    }
    return 23;
  }

  int minuteMinMake() {
    if (currentTime.year == minTime.year &&
        currentTime.month == minTime.month &&
        currentTime.day == minTime.day &&
        currentTime.hour == minTime.hour) {
      return minTime.minute;
    }
    return 0;
  }

  int minuteMaxMake() {
    if (currentTime.year == maxTime.year &&
        currentTime.month == maxTime.month &&
        currentTime.day == maxTime.day &&
        currentTime.hour == maxTime.hour) {
      return maxTime.minute;
    }
    return 59;
  }

  int secondMinMake() {
    if (currentTime.year == minTime.year &&
        currentTime.month == minTime.month &&
        currentTime.day == minTime.day &&
        currentTime.hour == minTime.hour &&
        currentTime.minute == minTime.minute) {
      return minTime.second;
    }
    return 0;
  }

  int secondMaxMake() {
    if (currentTime.year == maxTime.year &&
        currentTime.month == maxTime.month &&
        currentTime.day == maxTime.day &&
        currentTime.hour == maxTime.hour &&
        currentTime.minute == maxTime.minute) {
      return maxTime.second;
    }
    return 59;
  }

  @override
  void dispose() {
    super.dispose();
  }

  cancel() {
    Navigator.pop(context);
  }

  commit() {
    String data = '';
    if (widget.datetimeModeList.contains(DatetimeMode.yyyy)) {
      data += '${yearList[yearIndex]}-';
    }
    if (widget.datetimeModeList.contains(DatetimeMode.MM)) {
      data += '${zeroMake(monthList[monthIndex])}-';
    }
    if (widget.datetimeModeList.contains(DatetimeMode.dd)) {
      data += '${zeroMake(dayList[dayIndex])} ';
    }
    if (widget.datetimeModeList.contains(DatetimeMode.HH)) {
      data += '${zeroMake(hourList[hourIndex])}:';
    }
    if (widget.datetimeModeList.contains(DatetimeMode.mm)) {
      data += '${zeroMake(minuteList[minuteIndex])}:';
    }
    if (widget.datetimeModeList.contains(DatetimeMode.ss)) {
      data += '${zeroMake(secondList[secondIndex])}:';
    }
    data = data.substring(0, data.length - 1);
    Navigator.pop(context);
    widget.onTime(data);
  }

  zeroMake(int num) {
    if (num < 10) {
      return '0$num';
    }
    return num.toString();
  }

  onSelectedItemChanged(int data, int index, DatetimeMode mode) {
    if (mode == DatetimeMode.yyyy) {
      yearIndex = index;
      currentTime = DateTime(
          yearList[yearIndex],
          currentTime.month,
          currentTime.day,
          currentTime.hour,
          currentTime.minute,
          currentTime.second);
      monthMake();
      dayMake();
      hourMake();
      minuteMake();
      secondMake();
    }
    if (mode == DatetimeMode.MM) {
      monthIndex = index;
      currentTime = DateTime(
          currentTime.year,
          monthList[monthIndex],
          currentTime.day,
          currentTime.hour,
          currentTime.minute,
          currentTime.second);
      dayMake();
      hourMake();
      minuteMake();
      secondMake();
    }
    if (mode == DatetimeMode.dd) {
      dayIndex = index;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          dayList[dayIndex],
          currentTime.hour,
          currentTime.minute,
          currentTime.second);
      hourMake();
      minuteMake();
      secondMake();
    }
    if (mode == DatetimeMode.HH) {
      hourIndex = index;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          hourList[hourIndex],
          currentTime.minute,
          currentTime.second);
      minuteMake();
      secondMake();
    }
    if (mode == DatetimeMode.mm) {
      minuteIndex = index;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          currentTime.hour,
          minuteList[minuteIndex],
          currentTime.second);
      secondMake();
    }
    if (mode == DatetimeMode.ss) {
      secondIndex = index;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          currentTime.hour,
          currentTime.minute,
          secondList[secondIndex]);
    }
    setState(() {});
  }

  monthMake() {
    if (!widget.datetimeModeList.contains(DatetimeMode.MM)) {
      return;
    }
    monthList.clear();
    monthList
        .addAll(TimeUtil.calcMonth(begin: monthMinMake(), end: monthMaxMake()));
    if (monthIndex > monthList.length) {
      monthIndex = monthList.length - 1;
      currentTime = DateTime(
          currentTime.year,
          monthList[monthIndex],
          currentTime.day,
          currentTime.hour,
          currentTime.minute,
          currentTime.second);
    }
  }

  dayMake() {
    if (!widget.datetimeModeList.contains(DatetimeMode.dd)) {
      return;
    }
    dayList.clear();
    dayList.addAll(TimeUtil.calcDay(yearList[yearIndex], monthList[monthIndex],
        begin: dayMinMake(), end: dayMaxMake()));
    if (dayIndex > dayList.length) {
      dayIndex = dayList.length - 1;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          dayList[dayIndex],
          currentTime.hour,
          currentTime.minute,
          currentTime.second);
    }
  }

  hourMake() {
    if (!widget.datetimeModeList.contains(DatetimeMode.HH)) {
      return;
    }
    hourList.clear();
    hourList
        .addAll(TimeUtil.calcHour(begin: hourMinMake(), end: hourMaxMake()));
    if (hourIndex > hourList.length) {
      hourIndex = hourList.length - 1;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          hourList[hourIndex],
          currentTime.minute,
          currentTime.second);
    }
  }

  minuteMake() {
    if (!widget.datetimeModeList.contains(DatetimeMode.mm)) {
      return;
    }
    minuteList.clear();
    minuteList.addAll(TimeUtil.calcMinAndSecond(
        begin: minuteMinMake(), end: minuteMaxMake()));
    if (minuteIndex > minuteList.length) {
      minuteIndex = minuteList.length - 1;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          currentTime.hour,
          minuteList[minuteIndex],
          currentTime.second);
    }
  }

  secondMake() {
    if (!widget.datetimeModeList.contains(DatetimeMode.ss)) {
      return;
    }
    secondList.clear();
    secondList.addAll(TimeUtil.calcMinAndSecond(
        begin: secondMinMake(), end: secondMaxMake()));
    if (secondIndex > secondList.length) {
      secondIndex = secondList.length - 1;
      currentTime = DateTime(
          currentTime.year,
          currentTime.month,
          currentTime.day,
          currentTime.hour,
          currentTime.minute,
          secondList[secondIndex]);
    }
  }
}
